﻿using System.Diagnostics.Contracts;

namespace System.Reactive.Concurrency
{
	[ContractClass(typeof(ISchedulerContract))]
	public interface IScheduler
	{
		IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action);

		IDisposable Schedule<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action);

		IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action);
	}

	[ContractClassFor(typeof(IScheduler))]
	internal abstract class ISchedulerContract : IScheduler
	{
		public IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
		{
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public IDisposable Schedule<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action)
		{
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
		{
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}
	}
}